﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows.Media;

using InfFront.UICore;
using InfFront.InfoSources.Base;
using InfFront.InfoViews.Base;

namespace InfFront.InfoViews.WPF.Settings
{
    internal class MappedVisualSettingsInfoField : MappedInfoField
    {
        #region Private Variables
        #endregion Private Variables

        #region Initialization/Construction

        public MappedVisualSettingsInfoField()
        {
            Init();
        }

        public MappedVisualSettingsInfoField(IContainer container)
            : base(container)
        {
            container.Add(this);
            Init();
        }

        private void Init()
        {
        }

        #endregion Initialization/Construction

        public override object GetValue(object obj)
        {
            var infoViewEntity = (BaseInfoViewEntity)obj;
            var accessor = (SettingsAccessor) infoViewEntity.VisualSettings;
            return accessor.GetValue(MappingName, false);
        }

        public override void SetValue(object obj, object value)
        {
            var infoViewEntity = (BaseInfoViewEntity)obj;
            var accessor = (SettingsAccessor) infoViewEntity.VisualSettings;
            accessor.SetValue(MappingName, value, 
                              true // TODO: change this to *false* and support settings change rollbacks
                              );
        }
    }

    internal class MappedColorInfoField : MappedVisualSettingsInfoField
    {
        #region Private Variables
        internal static readonly string DEFAULT_COLOR_TITLE = "<Default>";
        private static readonly string DEFAULT_COLOR_VALUE = string.Empty;
        private static List<IInfoFieldEnumItem> enumItems;
        #endregion Private Variables

        #region Initialization/Construction

        static MappedColorInfoField()
        {
            enumItems = new List<IInfoFieldEnumItem>();

            enumItems.Add(new InfoFieldEnumItem() { Title = DEFAULT_COLOR_TITLE, Value = DEFAULT_COLOR_VALUE });
            AddEnumItem("AliceBlue", Colors.AliceBlue);
            AddEnumItem("AntiqueWhite", Colors.AntiqueWhite);
            AddEnumItem("Aqua", Colors.Aqua);
            AddEnumItem("Aquamarine", Colors.Aquamarine);
            AddEnumItem("Azure", Colors.Azure);
            AddEnumItem("Beige", Colors.Beige);
            AddEnumItem("Bisque", Colors.Bisque);
            AddEnumItem("Black", Colors.Black);
            AddEnumItem("BlanchedAlmond", Colors.BlanchedAlmond);
            AddEnumItem("Blue", Colors.Blue);
            AddEnumItem("BlueViolet", Colors.BlueViolet);
            AddEnumItem("Brown", Colors.Brown);
            AddEnumItem("BurlyWood", Colors.BurlyWood);
            AddEnumItem("CadetBlue", Colors.CadetBlue);
            AddEnumItem("Chartreuse", Colors.Chartreuse);
            AddEnumItem("Chocolate", Colors.Chocolate);
            AddEnumItem("Coral", Colors.Coral);
            AddEnumItem("CornflowerBlue", Colors.CornflowerBlue);
            AddEnumItem("Cornsilk", Colors.Cornsilk);
            AddEnumItem("Crimson", Colors.Crimson);
            //AddEnumItem("Cyan", Colors.Cyan);
            AddEnumItem("DarkBlue", Colors.DarkBlue);
            AddEnumItem("DarkCyan", Colors.DarkCyan);
            AddEnumItem("DarkGoldenrod", Colors.DarkGoldenrod);
            AddEnumItem("DarkGray", Colors.DarkGray);
            AddEnumItem("DarkGreen", Colors.DarkGreen);
            AddEnumItem("DarkKhaki", Colors.DarkKhaki);
            AddEnumItem("DarkMagenta", Colors.DarkMagenta);
            AddEnumItem("DarkOliveGreen", Colors.DarkOliveGreen);
            AddEnumItem("DarkOrange", Colors.DarkOrange);
            AddEnumItem("DarkOrchid", Colors.DarkOrchid);
            AddEnumItem("DarkRed", Colors.DarkRed);
            AddEnumItem("DarkSalmon", Colors.DarkSalmon);
            AddEnumItem("DarkSeaGreen", Colors.DarkSeaGreen);
            AddEnumItem("DarkSlateBlue", Colors.DarkSlateBlue);
            AddEnumItem("DarkSlateGray", Colors.DarkSlateGray);
            AddEnumItem("DarkTurquoise", Colors.DarkTurquoise);
            AddEnumItem("DarkViolet", Colors.DarkViolet);
            AddEnumItem("DeepPink", Colors.DeepPink);
            AddEnumItem("DeepSkyBlue", Colors.DeepSkyBlue);
            AddEnumItem("DimGray", Colors.DimGray);
            AddEnumItem("DodgerBlue", Colors.DodgerBlue);
            AddEnumItem("Firebrick", Colors.Firebrick);
            AddEnumItem("FloralWhite", Colors.FloralWhite);
            AddEnumItem("ForestGreen", Colors.ForestGreen);
            //AddEnumItem("Fuchsia", Colors.Fuchsia);
            AddEnumItem("Gainsboro", Colors.Gainsboro);
            AddEnumItem("GhostWhite", Colors.GhostWhite);
            AddEnumItem("Gold", Colors.Gold);
            AddEnumItem("Goldenrod", Colors.Goldenrod);
            AddEnumItem("Gray", Colors.Gray);
            AddEnumItem("Green", Colors.Green);
            AddEnumItem("GreenYellow", Colors.GreenYellow);
            AddEnumItem("Honeydew", Colors.Honeydew);
            AddEnumItem("HotPink", Colors.HotPink);
            AddEnumItem("IndianRed", Colors.IndianRed);
            AddEnumItem("Indigo", Colors.Indigo);
            AddEnumItem("Ivory", Colors.Ivory);
            AddEnumItem("Khaki", Colors.Khaki);
            AddEnumItem("Lavender", Colors.Lavender);
            AddEnumItem("LavenderBlush", Colors.LavenderBlush);
            AddEnumItem("LawnGreen", Colors.LawnGreen);
            AddEnumItem("LemonChiffon", Colors.LemonChiffon);
            AddEnumItem("LightBlue", Colors.LightBlue);
            AddEnumItem("LightCoral", Colors.LightCoral);
            AddEnumItem("LightCyan", Colors.LightCyan);
            AddEnumItem("LightGoldenrodYellow", Colors.LightGoldenrodYellow);
            AddEnumItem("LightGray", Colors.LightGray);
            AddEnumItem("LightGreen", Colors.LightGreen);
            AddEnumItem("LightPink", Colors.LightPink);
            AddEnumItem("LightSalmon", Colors.LightSalmon);
            AddEnumItem("LightSeaGreen", Colors.LightSeaGreen);
            AddEnumItem("LightSkyBlue", Colors.LightSkyBlue);
            AddEnumItem("LightSlateGray", Colors.LightSlateGray);
            AddEnumItem("LightSteelBlue", Colors.LightSteelBlue);
            AddEnumItem("LightYellow", Colors.LightYellow);
            AddEnumItem("Lime", Colors.Lime);
            AddEnumItem("LimeGreen", Colors.LimeGreen);
            AddEnumItem("Linen", Colors.Linen);
            AddEnumItem("Magenta", Colors.Magenta);
            AddEnumItem("Maroon", Colors.Maroon);
            AddEnumItem("MediumAquamarine", Colors.MediumAquamarine);
            AddEnumItem("MediumBlue", Colors.MediumBlue);
            AddEnumItem("MediumOrchid", Colors.MediumOrchid);
            AddEnumItem("MediumPurple", Colors.MediumPurple);
            AddEnumItem("MediumSeaGreen", Colors.MediumSeaGreen);
            AddEnumItem("MediumSlateBlue", Colors.MediumSlateBlue);
            AddEnumItem("MediumSpringGreen", Colors.MediumSpringGreen);
            AddEnumItem("MediumTurquoise", Colors.MediumTurquoise);
            AddEnumItem("MediumVioletRed", Colors.MediumVioletRed);
            AddEnumItem("MidnightBlue", Colors.MidnightBlue);
            AddEnumItem("MintCream", Colors.MintCream);
            AddEnumItem("MistyRose", Colors.MistyRose);
            AddEnumItem("Moccasin", Colors.Moccasin);
            AddEnumItem("NavajoWhite", Colors.NavajoWhite);
            AddEnumItem("Navy", Colors.Navy);
            AddEnumItem("OldLace", Colors.OldLace);
            AddEnumItem("Olive", Colors.Olive);
            AddEnumItem("OliveDrab", Colors.OliveDrab);
            AddEnumItem("Orange", Colors.Orange);
            AddEnumItem("OrangeRed", Colors.OrangeRed);
            AddEnumItem("Orchid", Colors.Orchid);
            AddEnumItem("PaleGoldenrod", Colors.PaleGoldenrod);
            AddEnumItem("PaleGreen", Colors.PaleGreen);
            AddEnumItem("PaleTurquoise", Colors.PaleTurquoise);
            AddEnumItem("PaleVioletRed", Colors.PaleVioletRed);
            AddEnumItem("PapayaWhip", Colors.PapayaWhip);
            AddEnumItem("PeachPuff", Colors.PeachPuff);
            AddEnumItem("Peru", Colors.Peru);
            AddEnumItem("Pink", Colors.Pink);
            AddEnumItem("Plum", Colors.Plum);
            AddEnumItem("PowderBlue", Colors.PowderBlue);
            AddEnumItem("Purple", Colors.Purple);
            AddEnumItem("Red", Colors.Red);
            AddEnumItem("RosyBrown", Colors.RosyBrown);
            AddEnumItem("RoyalBlue", Colors.RoyalBlue);
            AddEnumItem("SaddleBrown", Colors.SaddleBrown);
            AddEnumItem("Salmon", Colors.Salmon);
            AddEnumItem("SandyBrown", Colors.SandyBrown);
            AddEnumItem("SeaGreen", Colors.SeaGreen);
            AddEnumItem("SeaShell", Colors.SeaShell);
            AddEnumItem("Sienna", Colors.Sienna);
            AddEnumItem("Silver", Colors.Silver);
            AddEnumItem("SkyBlue", Colors.SkyBlue);
            AddEnumItem("SlateBlue", Colors.SlateBlue);
            AddEnumItem("SlateGray", Colors.SlateGray);
            AddEnumItem("Snow", Colors.Snow);
            AddEnumItem("SpringGreen", Colors.SpringGreen);
            AddEnumItem("SteelBlue", Colors.SteelBlue);
            AddEnumItem("Tan", Colors.Tan);
            AddEnumItem("Teal", Colors.Teal);
            AddEnumItem("Thistle", Colors.Thistle);
            AddEnumItem("Tomato", Colors.Tomato);
            //AddEnumItem("Transparent", Colors.Transparent);
            AddEnumItem("Turquoise", Colors.Turquoise);
            AddEnumItem("Violet", Colors.Violet);
            AddEnumItem("Wheat", Colors.Wheat);
            AddEnumItem("White", Colors.White);
            AddEnumItem("WhiteSmoke", Colors.WhiteSmoke);
            AddEnumItem("Yellow", Colors.Yellow);
            AddEnumItem("YellowGreen", Colors.YellowGreen);
        }

        private static void AddEnumItem(string title, Color? value)
        {
            enumItems.Add(new InfoFieldEnumItem() { Title = title, Value = (value == null)? null: value.ToString() });
        }

        internal static IEnumerable<IInfoFieldEnumItem> EnumItems // to be used at the plot legend selector
        {
            get { return enumItems; }
        }

        public MappedColorInfoField()
        {
            Init();
        }

        public MappedColorInfoField(IContainer container)
            : base(container)
        {
            container.Add(this);
            Init();
        }

        private void Init()
        {
            base.DataTypeKind = BaseDataType.Type.String;
            this.OnGetEnumValues += new OnGetInfoFieldEnumValues(MappedColorInfoField_OnGetEnumValues);
            base.IsEnum = true;
        }

        #endregion Initialization/Construction

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new BaseDataType.Type DataTypeKind
        {
            get { return base.DataTypeKind; }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new BaseDataType DataTypeParams
        {
            get { return base.DataTypeParams; }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new bool IsEnum
        {
            get { return base.IsEnum; }
        }

        public override object GetValue(object obj)
        {
            var val = (Color?)base.GetValue(obj);
            if (val == null)
                return DEFAULT_COLOR_VALUE;
            return val.ToString();
        }

        public override void SetValue(object obj, object value)
        {
            var strVal = (string)value;
            object val = null;
            if (strVal != null && strVal != DEFAULT_COLOR_VALUE)
                val = ColorConverter.ConvertFromString(strVal);
            base.SetValue(obj, val);
        }

        private void MappedColorInfoField_OnGetEnumValues(object sender, GetInfoFieldEnumValuesArgs args)
        {
            args.Items = enumItems;
        }

    }

    internal class MappedMainFrameStyleField : MappedVisualSettingsInfoField
    {
        #region Private Variables
        private static readonly string DEFAULT_STYLE_TITLE = "<Default>";
        private static readonly string DEFAULT_STYLE_VALUE = string.Empty;
        private static List<IInfoFieldEnumItem> enumItems;
        #endregion Private Variables

        #region Initialization/Construction

        static MappedMainFrameStyleField()
        {
            enumItems = new List<IInfoFieldEnumItem>();

            enumItems.Add(new InfoFieldEnumItem() { Title = DEFAULT_STYLE_TITLE, Value = DEFAULT_STYLE_VALUE });
            var type = typeof(MainFrameStyle);
            foreach (var v in Enum.GetValues(type))
            {
                string vString = v.ToString();
                System.Reflection.FieldInfo fi = type.GetField(vString);
                DescriptionAttribute[] attrs =
                    (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
                var item = new InfoFieldEnumItem() { Title = (attrs.Length > 0) ? attrs[0].Description : vString, Value = vString };
                enumItems.Add(item);
            }
        }

        private static void AddEnumItem(string title, Color? value)
        {
            enumItems.Add(new InfoFieldEnumItem() { Title = title, Value = (value == null) ? null : value.ToString() });
        }

        public MappedMainFrameStyleField()
        {
            Init();
        }

        public MappedMainFrameStyleField(IContainer container)
            : base(container)
        {
            container.Add(this);
            Init();
        }

        private void Init()
        {
            base.DataTypeKind = BaseDataType.Type.String;
            this.OnGetEnumValues += new OnGetInfoFieldEnumValues(MappedMainFrameStyleField_OnGetEnumValues);
            base.IsEnum = true;
        }

        #endregion Initialization/Construction

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new BaseDataType.Type DataTypeKind
        {
            get { return base.DataTypeKind; }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new BaseDataType DataTypeParams
        {
            get { return base.DataTypeParams; }
        }

        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new bool IsEnum
        {
            get { return base.IsEnum; }
        }

        public override object GetValue(object obj)
        {
            var val = (MainFrameStyle?)base.GetValue(obj);
            if (val == null)
                return DEFAULT_STYLE_VALUE;
            return val.ToString();
        }

        public override void SetValue(object obj, object value)
        {
            var strVal = (string)value;
            object val = null;
            if (strVal != null && strVal != DEFAULT_STYLE_VALUE)
                val = Enum.Parse(typeof(MainFrameStyle), strVal);
            base.SetValue(obj, val);
        }

        private void MappedMainFrameStyleField_OnGetEnumValues(object sender, GetInfoFieldEnumValuesArgs args)
        {
            args.Items = enumItems;
        }

    }
}
